//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.tuiofx.internal.base;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.Animation.Status;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.event.EventTarget;
import javafx.scene.Node;
import javafx.util.Duration;
import org.tuiofx.Configuration;
import org.tuiofx.internal.gesture.GestureRecognizer;
import org.tuiofx.internal.gesture.GestureTracker;
import org.tuiofx.internal.gesture.LongPressDetector;
import org.tuiofx.internal.gesture.MouseEventRecognizer;
import org.tuiofx.internal.gesture.RotateGestureRecognizer;
import org.tuiofx.internal.gesture.ScrollGestureRecognizer;
import org.tuiofx.internal.gesture.SwipeGestureRecognizer;
import org.tuiofx.internal.gesture.TouchRecognizer;
import org.tuiofx.internal.gesture.TuioTouchPoint;
import org.tuiofx.internal.gesture.ZoomGestureRecognizer;
import org.tuiofx.internal.util.LogUtils;
import org.tuiofx.internal.util.PrettyPrintingMap;

public class GestureHandler {
    private final HashMap<EventTarget, Timeline> killGestureTimlelineMap;
    private final Configuration config;
    Vector<GestureRecognizer> gestureRecognizers = new Vector<>();
    ConcurrentHashMap<EventTarget, ArrayList<GestureRecognizer>> gesturesTarget = new ConcurrentHashMap<>();
    HashMap<Node, GestureRecognizer> targetGestureTrackerMap = new HashMap<>();
    HashMap<EventTarget, LongPressDetector> longPressDectectorTarget = new HashMap<>();
    private Map<EventTarget, ArrayList<TuioTouchPoint>> targetNodeTouchesMap = new HashMap<>();
    private final PrettyPrintingMap printTouchPoints;
    private double killGestureDuration = 10000.0;
    private boolean killGesture = true;

    public GestureHandler(Configuration config) {
        this.printTouchPoints = new PrettyPrintingMap(this.targetNodeTouchesMap);
        this.killGestureTimlelineMap = new HashMap<>();
        this.config = config;
    }

    private void addAllGestureRecognizer(Node targetNode) {
        MouseEventRecognizer mouse = new MouseEventRecognizer(targetNode, this.config);
        this.addGestureRecognizer(new TouchRecognizer(targetNode, this.config));
        this.addGestureRecognizer(mouse);
        this.addGestureRecognizer(new ScrollGestureRecognizer(targetNode, this.config));
        this.addGestureRecognizer(new RotateGestureRecognizer(targetNode, this.config));
        this.addGestureRecognizer(new ZoomGestureRecognizer(targetNode, this.config));
        this.addGestureRecognizer(new SwipeGestureRecognizer(targetNode, this.config));
        if (this.killGesture) {
            this.createKillGestureTimer(targetNode);
        }

    }

    private void addGestureRecognizer(GestureRecognizer gestureRecognizer) {
        ArrayList<GestureRecognizer> gestures = this.gesturesTarget.get(gestureRecognizer.getEventTarget());
        if (gestures != null) {
            gestures.add(gestureRecognizer);
        } else {
            gestures = new ArrayList<>();
            gestures.add(gestureRecognizer);
            this.gesturesTarget.put(gestureRecognizer.getEventTarget(), gestures);
        }

    }

    private GestureRecognizer getTargetGestureTracker(Node target) {
        GestureRecognizer trackerNode = (GestureRecognizer) this.targetGestureTrackerMap.get(target);
        if (trackerNode == null) {
            trackerNode = new GestureTracker(target, this.config);
            this.targetGestureTrackerMap.put(target, trackerNode);
        }

        return (GestureRecognizer) trackerNode;
    }

    private void createKillGestureTimer(final EventTarget targetNode) {
        Timeline timeline = (Timeline) this.killGestureTimlelineMap.get(targetNode);
        if (timeline == null) {
            final Timeline killGestureTimleline = new Timeline();
            killGestureTimleline.getKeyFrames().add(new KeyFrame(Duration.millis(this.killGestureDuration), new EventHandler<ActionEvent>() {
                public void handle(ActionEvent event) {
                    ArrayList<TuioTouchPoint> touches = GestureHandler.this.targetNodeTouchesMap.get(targetNode);
                    if (touches == null || touches.isEmpty()) {
                        killGestureTimleline.stop();
                        GestureHandler.this.gesturesTarget.remove(targetNode);
                    }

                }
            }, new KeyValue[0]));
            killGestureTimleline.setCycleCount(-1);
            this.killGestureTimlelineMap.put(targetNode, killGestureTimleline);
        }

    }

    private void startKillGestureTimer(EventTarget targetNode) {
        final Timeline killGestureTimleline = (Timeline) this.killGestureTimlelineMap.get(targetNode);
        if (killGestureTimleline == null) {
            LogUtils.error("killGestureTimleline should not bee null!");
        }

        Platform.runLater(new Runnable() {
            public void run() {
                if (killGestureTimleline.getStatus().equals(Status.RUNNING)) {
                    killGestureTimleline.stop();
                }

                killGestureTimleline.play();
            }
        });
    }

    public void touchesBegan(TuioTouchPoint touchPoint) {
        if (touchPoint.getTargetNode() != null) {
            ArrayList<TuioTouchPoint> nodeTouchPointList = this.targetNodeTouchesMap.get(touchPoint.getTargetNode());
            if (nodeTouchPointList == null) {
                nodeTouchPointList = new ArrayList<>();
                this.targetNodeTouchesMap.put(touchPoint.getTargetNode(), nodeTouchPointList);
            }

            nodeTouchPointList.add(touchPoint);
            if (this.config.isShowCursorEnabled()) {
                GestureRecognizer tracker = this.getTargetGestureTracker((Node) touchPoint.getTargetNode());
                tracker.preTouchesBegan(touchPoint);
            }

            ArrayList<GestureRecognizer> gestures = this.gesturesTarget.get(touchPoint.getTargetNode());
            if (gestures == null) {
                this.addAllGestureRecognizer((Node) touchPoint.getTargetNode());
                gestures = this.gesturesTarget.get(touchPoint.getTargetNode());
            }

            if (gestures != null) {
                Iterator<GestureRecognizer> var4 = gestures.iterator();

                while (var4.hasNext()) {
                    GestureRecognizer _gesture = var4.next();
                    _gesture.preTouchesBegan(touchPoint);
                }
            }

        }
    }

    public void touchesMove(TuioTouchPoint touchPoint) {
        if (touchPoint.getTargetNode() != null && this.targetNodeTouchesMap.containsKey(touchPoint.getTargetNode())) {
            if (this.config.isShowCursorEnabled()) {
                GestureRecognizer tracker = this.getTargetGestureTracker((Node) touchPoint.getTargetNode());
                tracker.preTouchesMove(touchPoint);
            }

            ArrayList<GestureRecognizer> gestures = this.gesturesTarget.get(touchPoint.getTargetNode());
            if (gestures != null) {
                Iterator<GestureRecognizer> var3 = gestures.iterator();

                while (var3.hasNext()) {
                    GestureRecognizer _gesture = var3.next();
                    _gesture.preTouchesMove(touchPoint);
                }

            }
        }
    }

    public void touchesEnd(TuioTouchPoint touchPoint) {
        if (touchPoint.getTargetNode() != null) {
            ArrayList<TuioTouchPoint> targetNodeTouchesList = this.targetNodeTouchesMap.get(touchPoint.getTargetNode());
            if (targetNodeTouchesList != null) {
                targetNodeTouchesList.remove(touchPoint);
            }

            if (this.config.isShowCursorEnabled()) {
                GestureRecognizer tracker = this.getTargetGestureTracker((Node) touchPoint.getTargetNode());
                tracker.preTouchesEnd(touchPoint);
            }

            ArrayList<GestureRecognizer> gestures = this.gesturesTarget.get(touchPoint.getTargetNode());
            if (gestures != null) {
                Iterator<GestureRecognizer> var4 = gestures.iterator();

                while (var4.hasNext()) {
                    GestureRecognizer _gesture = var4.next();
                    _gesture.preTouchesEnd(touchPoint);
                }

                if (this.killGesture) {
                    this.startKillGestureTimer(touchPoint.getTargetNode());
                }
            }

        }
    }
}
